home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / sorgenti vari / wolf3dmacsource.sit / Wolf3DMacSource / Level.c < prev    next >
C/C++ Source or Header  |  1994-10-19  |  17KB  |  733 lines

  1. #include "wolfdef.h"
  2. #include <string.h>
  3.  
  4. /* static object info*/
  5.  
  6. /* List of bad guy sprites */
  7.  
  8. static Word DKnightSprs[] = {
  9. S_DKNIGHT_ATK1,
  10. S_DKNIGHT_ATK2,
  11. S_DKNIGHT_ATK3,
  12. S_DKNIGHT_ATK4,
  13. S_DKNIGHT_WLK1,
  14. S_DKNIGHT_WLK2,
  15. S_DKNIGHT_WLK3,
  16. S_DKNIGHT_WLK4,
  17. S_DKNIGHT_DTH1,
  18. S_DKNIGHT_DTH2,
  19. S_DKNIGHT_DTH3,S_G_KEY,0};
  20.  
  21. static Word DogSprs[] = {
  22. S_DOG_ATK1,
  23. S_DOG_ATK2,
  24. S_DOG_ATK3,
  25. S_DOG_WLK1,
  26. S_DOG_WLK2,
  27. S_DOG_WLK3,
  28. S_DOG_WLK4,
  29. S_DOG_DTH1,
  30. S_DOG_DTH2,
  31. S_DOG_DTH3,0};
  32.  
  33. static Word NaziSprs[] = {
  34. S_GUARD_ATK1,
  35. S_GUARD_ATK2,
  36. S_GUARD_ATK3,
  37. S_GUARD_WLK1,
  38. S_GUARD_WLK2,
  39. S_GUARD_WLK3,
  40. S_GUARD_WLK4,
  41. S_GUARD_PAIN,
  42. S_GUARD_DTH1,
  43. S_GUARD_DTH2,
  44. S_GUARD_DTH3,S_AMMO,0};
  45.  
  46. static Word HansSprs[] = {
  47. S_HANS_ATK1,
  48. S_HANS_ATK2,
  49. S_HANS_ATK3,
  50. S_HANS_WLK1,
  51. S_HANS_WLK2,
  52. S_HANS_WLK3,
  53. S_HANS_WLK4,
  54. S_HANS_DTH1,
  55. S_HANS_DTH2,
  56. S_HANS_DTH3,S_G_KEY,0};
  57.  
  58. static Word HitlerSprs[] = {
  59. S_HITLER_ATK1,
  60. S_HITLER_ATK2,
  61. S_HITLER_ATK3,
  62. S_HITLER_WLK1,
  63. S_HITLER_WLK2,
  64. S_HITLER_WLK3,
  65. S_HITLER_WLK4,
  66. S_HITLER_DTH1,
  67. S_HITLER_DTH2,
  68. S_HITLER_DTH3,
  69. S_MHITLER_ATK1,
  70. S_MHITLER_ATK2,
  71. S_MHITLER_ATK3,
  72. S_MHITLER_DIE1,
  73. S_MHITLER_DIE2,
  74. S_MHITLER_DIE3,
  75. S_MHITLER_DIE4,
  76. S_MHITLER_WLK1,
  77. S_MHITLER_WLK2,
  78. S_MHITLER_WLK3,
  79. S_MHITLER_WLK4,0};
  80.  
  81. static Word UberSprs[] = {
  82. S_UBER_ATK1,
  83. S_UBER_ATK2,
  84. S_UBER_ATK3,
  85. S_UBER_ATK4,
  86. S_UBER_WLK1,
  87. S_UBER_WLK2,
  88. S_UBER_WLK3,
  89. S_UBER_WLK4,
  90. S_UBER_DTH1,
  91. S_UBER_DTH2,
  92. S_UBER_DTH3,S_G_KEY,0};
  93.  
  94. static Word MutantSprs[] = {
  95. S_MUTANT_ATK1,
  96. S_MUTANT_ATK2,
  97. S_MUTANT_ATK3,
  98. S_MUTANT_WLK1,
  99. S_MUTANT_WLK2,
  100. S_MUTANT_WLK3,
  101. S_MUTANT_WLK4,
  102. S_MUTANT_PAIN,
  103. S_MUTANT_DTH1,
  104. S_MUTANT_DTH2,
  105. S_MUTANT_DTH3,S_AMMO,0};
  106.  
  107. static Word OfficerSprs[] = {
  108. S_OFFICER_ATK1,
  109. S_OFFICER_ATK2,
  110. S_OFFICER_ATK3,
  111. S_OFFICER_WLK1,
  112. S_OFFICER_WLK2,
  113. S_OFFICER_WLK3,
  114. S_OFFICER_WLK4,
  115. S_OFFICER_PAIN,
  116. S_OFFICER_DTH1,
  117. S_OFFICER_DTH2,
  118. S_OFFICER_DTH3,S_AMMO,0};
  119.  
  120. static Word SchabbsSpr[] = {
  121. S_SCHABBS_ATK1,
  122. S_SCHABBS_ATK2,
  123. S_SCHABBS_WLK1,
  124. S_SCHABBS_WLK2,
  125. S_SCHABBS_WLK3,
  126. S_SCHABBS_WLK4,
  127. S_SCHABBS_DTH1,
  128. S_SCHABBS_DTH2,
  129. S_SCHABBS_DTH3,S_G_KEY,0};
  130.  
  131. static Word SSSprs[] = {
  132. S_SS_ATK1,
  133. S_SS_ATK2,
  134. S_SS_ATK3,
  135. S_SS_WLK1,
  136. S_SS_WLK2,
  137. S_SS_WLK3,
  138. S_SS_WLK4,
  139. S_SS_PAIN,
  140. S_SS_DTH1,
  141. S_SS_DTH2,
  142. S_SS_DTH3,S_MACHINEGUN,S_AMMO,0};
  143.  
  144. static Word TransSprs[] = {
  145. S_TRANS_ATK1,
  146. S_TRANS_ATK2,
  147. S_TRANS_ATK3,
  148. S_TRANS_WLK1,
  149. S_TRANS_WLK2,
  150. S_TRANS_WLK3,
  151. S_TRANS_WLK4,
  152. S_TRANS_DTH1,
  153. S_TRANS_DTH2,
  154. S_TRANS_DTH3,S_G_KEY,0};
  155.  
  156. static Byte EnemyHits[16];
  157.  
  158. static Word *EnemySprs[] = {    /* This list MUST match class_t! */
  159. NaziSprs,
  160. OfficerSprs,
  161. SSSprs,
  162. DogSprs,
  163. MutantSprs,
  164. HansSprs,
  165. SchabbsSpr,
  166. TransSprs,
  167. UberSprs,
  168. DKnightSprs,
  169. HitlerSprs,
  170. HitlerSprs
  171. };
  172.  
  173.  
  174. static Byte WallHits[256];
  175.  
  176. Word staticflags[] = {
  177. 0,                    /*S_WATER_PUDDLE,*/
  178. TI_BLOCKMOVE,        /*S_GREEN_BARREL,*/
  179. TI_BLOCKMOVE,        /*S_CHAIR_TABLE,*/
  180. TI_BLOCKMOVE,        /*S_FLOOR_LAMP,*/
  181. 0,                    /*S_CHANDELIER,*/
  182. TI_GETABLE,            /*S_DOG_FOOD,*/
  183. TI_BLOCKMOVE,        /*S_COLUMN,*/
  184. TI_BLOCKMOVE,        /*S_POTTED_TREE,*/
  185.  
  186. TI_BLOCKMOVE,        /*S_FLAG,*/
  187. TI_BLOCKMOVE,        /*S_POTTED_PLANT,*/
  188. TI_BLOCKMOVE,        /*S_BLUE_POT,*/
  189. 0,                    /*S_DEBRIS1,*/
  190. 0,                    /*S_LIGHT,*/
  191. 0,                    /*S_BUCKET,*/
  192. TI_BLOCKMOVE,        /*S_ARMOUR,*/
  193. TI_BLOCKMOVE,        /*S_CAGE,*/
  194.  
  195. TI_GETABLE,            /*S_G_KEY,*/
  196. TI_GETABLE,            /*S_S_KEY,*/
  197. TI_GETABLE,            /*S_BANDOLIER*/
  198. TI_GETABLE,            /*S_AMMOCASE,*/
  199. TI_GETABLE,            /*S_FOOD,*/
  200. TI_GETABLE,            /*S_HEALTH,*/
  201. TI_GETABLE,            /*S_AMMO,*/
  202. TI_GETABLE,            /*S_MACHINEGUN,*/
  203.  
  204. TI_GETABLE,            /*S_CHAINGUN,*/
  205. TI_GETABLE,            /*S_CROSS,*/
  206. TI_GETABLE,            /*S_CHALICE,*/
  207. TI_GETABLE,            /*S_CHEST,*/
  208. TI_GETABLE,            /*S_CROWN,*/
  209. TI_GETABLE,            /*S_ONEUP,*/
  210. TI_BLOCKMOVE,        /*S_WOOD_BARREL,*/
  211. TI_BLOCKMOVE,        /*S_WATER_WELL,*/
  212. TI_GETABLE,            /*S_FLAMETHROWER */
  213. TI_GETABLE,            /*S_GASCAN */
  214. TI_GETABLE,            /*S_LAUNCHER */
  215. TI_GETABLE            /*S_MISSILES */
  216. };
  217.  
  218. /**********************************
  219.  
  220.     Spawn a static object at x,y
  221.  
  222. **********************************/
  223.  
  224. void SpawnStatic(Word x,Word y,Word shape)
  225. {    
  226.     Word *TilePtr;
  227.     static_t *StatPtr;
  228.     
  229.     if (numstatics>=MAXSTATICS) {
  230.         return;                /* Oh oh!! */
  231.     }
  232.     TilePtr = &tilemap[y][x];        /* Precalc tile pointer */
  233.     StatPtr = &statics[numstatics];
  234.     StatPtr->x = (x<<FRACBITS)+0x80;    /* Set the pixel X */
  235.     StatPtr->y = (y<<FRACBITS)+0x80;    /* Set the pixel Y */
  236.     StatPtr->areanumber = TilePtr[0] & TI_NUMMASK;    /* Mask off the area number */
  237.     TilePtr[0] |= staticflags[shape];
  238.  
  239.     shape += S_WATER_PUDDLE;    /* Init the shape number */
  240.     WallHits[shape] = 1;        /* Load in this shape */
  241.     StatPtr->pic = shape;        /* Set the object's shape */
  242.     switch (shape) {
  243.     case S_CROSS:
  244.     case S_CHALICE:
  245.     case S_CHEST:
  246.     case S_CROWN:
  247.     case S_ONEUP:
  248.         ++gamestate.treasuretotal;    /* Mark this as treasure */
  249.     }
  250.     ++numstatics;                /* I have one more item */
  251. }
  252.  
  253. /**********************************
  254.  
  255.     Spawn the player at x,y
  256.  
  257. **********************************/
  258.  
  259. void SpawnPlayer(Word x,Word y,Word dir)
  260. {
  261.     gamestate.viewangle = (1-dir)*ANGLES/4;    /* Get the basic viewing angle */
  262.     actors[0].x = (x<<FRACBITS)+0x80;    /* Save the X coord */
  263.     actors[0].y = (y<<FRACBITS)+0x80;    /* Save the Y coord */
  264.     actors[0].class = CL_PLAYER;    /* This is the player */
  265.     actors[0].areanumber = tilemap[y][x]&TI_NUMMASK;    /* Which area? */
  266.     ConnectCount = 0;        /* Zap the interconnects */
  267.     ConnectAreas();            /* Init the area table */
  268. }
  269.  
  270. /**********************************
  271.  
  272.     Spawn an actor at a specific x,y
  273.  
  274. **********************************/
  275.  
  276. void SpawnStand(Word x,Word y,class_t which)
  277. {
  278.     stateindex_t state;
  279.     classinfo_t    *info;
  280.     actor_t *ActorPtr;
  281.     Word *TilePtr;
  282.     Word tile;
  283.     
  284.     if (numactors==MAXACTORS) {    /* Too many actors already? */
  285.         return;                    /* Exit */
  286.     }
  287.  
  288.     EnemyHits[which] = 1;
  289.     info = &classinfo[which];    /* Get the pointer to the basic info */
  290.     state = info->standstate;    /* Get the state logic value */
  291.     ActorPtr = &actors[numactors];    /* Get the pointer to the new actor entry */
  292.     TilePtr = &tilemap[y][x];    /* Pointer to the current tile */
  293.     tile = TilePtr[0];            /* What's in the tile? */
  294.     
  295.     ActorPtr->x = (x<<FRACBITS)+0x80;    /* Init the x and y */
  296.     ActorPtr->y = (y<<FRACBITS)+0x80;
  297.     ActorPtr->pic = states[state].shapenum;    /* What picture to display? */
  298.     ActorPtr->ticcount = states[state].tictime;    /* Initial tick count */
  299.     ActorPtr->state = state;
  300.     ActorPtr->flags = FL_SHOOTABLE | FL_NOTMOVING;    /* You can shoot it */
  301.     ActorPtr->distance = 0;            /* No distance to travel */
  302.     ActorPtr->dir = nodir;                /* No direction of travel */
  303.     ActorPtr->areanumber = tile&TI_NUMMASK;    /* Area in */
  304.     ActorPtr->reacttime = 0;    /* Reaction time */
  305.     TilePtr[0] = tile | TI_ACTOR;    /* Mark as a bad guy */
  306.     MapPtr->tilemap[y][x] = numactors;    /* Save the actor # */
  307.     ActorPtr->goalx = x;        /* Don't travel anywhere */
  308.     ActorPtr->goaly = y;
  309.     ActorPtr->class = which;    /* Actor type */
  310.     ActorPtr->speed = info->speed;    /* Basic speed */
  311.     ActorPtr->hitpoints = info->hitpoints;    /* Starting hit points */
  312.     ++numactors;    /* I now add one more actor to the list */
  313.     ++gamestate.killtotal;        /* Another critter must die! */
  314. }
  315.  
  316.  
  317. /**********************************
  318.  
  319.     Spawn an actor at a specific x,y and ALSO set the ambush flag
  320.  
  321. **********************************/
  322.  
  323. void SpawnAmbush(Word x,Word y,class_t which)
  324. {
  325.     actor_t *ActorPtr;
  326.     
  327.     ActorPtr = &actors[numactors];    /* Get the pointer to the new actor entry */
  328.     SpawnStand(x,y,which);        /* Fill in all the entries */
  329.     ActorPtr->flags |= FL_AMBUSH;    /* Set the ambush flag */
  330. }
  331.  
  332. /**********************************
  333.  
  334.     Spawn a door at the specified x,y
  335.  
  336. **********************************/
  337.  
  338. void SpawnDoor(Word x,Word y,Word type)
  339. {
  340.     door_t *door;
  341.     Word *TilePtr;
  342.     
  343.     if (numdoors==MAXDOORS) {
  344.         return;
  345.     }
  346.     
  347.     TilePtr = &tilemap[y-1][x];    /* Pointer to the tile (-1 y) for door->area index */
  348.     door = &doors[numdoors];    /* Pointer to the door record */
  349.     
  350.     door->position = 0;        /* doors start out fully closed*/
  351.     door->tilex    = x;
  352.     door->tiley    = y;
  353.     door->info    = type-90;    /* Set the door type */
  354.     door->action = DR_CLOSED;    /* Mark as closed */
  355.     TilePtr[MAPSIZE] = (TI_DOOR|TI_BLOCKMOVE|TI_BLOCKSIGHT)| numdoors;
  356.  
  357.     if (type & 1) {    /* horizontal*/
  358.         door->area1 = TilePtr[MAPSIZE*2] & TI_NUMMASK;    /* One cell below */
  359.         door->area2 = TilePtr[0] & TI_NUMMASK;            /* One cell above */
  360.     } else {
  361.         door->area1 = TilePtr[MAPSIZE-1] & TI_NUMMASK;    /* One cell left */
  362.         door->area2 = TilePtr[MAPSIZE+1] & TI_NUMMASK;    /* One cell right */
  363.     }
  364.     ++numdoors;
  365. }
  366.  
  367. /**********************************
  368.  
  369.     Spawn a pushwall track at the specified x,y
  370.  
  371. **********************************/
  372.  
  373. void AddPWallTrack(Word x,Word y,Word tile)
  374. {
  375.     Byte *TextPtr;
  376.     if (x>=MAPSIZE || y>=MAPSIZE) {
  377.         return;        /* pushwall is off the edge of a map*/
  378.     }
  379.     TextPtr = &textures[MAPSIZE+x][y];
  380.     if (TextPtr[0] != 0xff) {    /* Already marked? */
  381.         return;                    /* solid wall*/
  382.     }
  383.     TextPtr[0] = tile + 1;        /* Save the tile # */
  384.     textures[y][x] = tile;        /* Mark the texture index */
  385. }
  386.  
  387. /**********************************
  388.  
  389.     Spawn a pushwall at the specified x,y
  390.  
  391. **********************************/
  392.  
  393. void SpawnPushwall(Word x,Word y,Word tile)
  394. {
  395.     ++gamestate.secrettotal;        /* Secret area! */
  396.     tilemap[y][x] |= (TI_BLOCKMOVE | TI_BLOCKSIGHT | TI_PUSHWALL);
  397. /* directly set texture values for rendering*/
  398.     tile = (tile-1)<<1;
  399.     AddPWallTrack(x, y, tile);
  400.     AddPWallTrack(x-1, y, tile);
  401.     AddPWallTrack(x-2, y, tile);
  402.     AddPWallTrack(x+1, y, tile);
  403.     AddPWallTrack(x+2, y, tile);
  404.     AddPWallTrack(x, y-1, tile);
  405.     AddPWallTrack(x, y-2, tile);
  406.     AddPWallTrack(x, y+1, tile);
  407.     AddPWallTrack(x, y+2, tile);
  408. }
  409.  
  410. /**********************************
  411.  
  412.     Spawn an elevator at the specified x,y
  413.  
  414. **********************************/
  415.  
  416. void SpawnElevator(Word x,Word y)
  417. {
  418.     elevatorx = x;    /* for easy mode cheating*/
  419.     elevatory = y;
  420.     tilemap[y][x] |= TI_BLOCKMOVE | TI_SWITCH;
  421. }
  422.  
  423. /**********************************
  424.  
  425.     Spawn the outside at the specified x,y
  426.  
  427. **********************************/
  428.  
  429. void SpawnOut(Word x,Word y)
  430. {
  431.     /*tilemap[y][x] |= TI_BLOCKMOVE | TI_SWITCH;*/
  432. }
  433.  
  434. /**********************************
  435.  
  436.     Spawn a secret item at the specified x,y
  437.  
  438. **********************************/
  439.  
  440. void SpawnSecret(Word x,Word y)
  441. {
  442.     tilemap[y][x] |= TI_BLOCKMOVE | TI_SECRET;
  443. }
  444.  
  445. /**********************************
  446.  
  447.     Spawn all actors and mark down special places
  448.     A spawn record is (x,y,type)
  449.     
  450. **********************************/
  451.  
  452. void SpawnThings(void)
  453. {
  454.     Word x,y;        /* Temp x,y */
  455.     Word type;        /* Item to spawn */
  456.     Byte *spawn_p;
  457.     Word Count;        /* Number of items to create */
  458.     Word *EnemyPtr;
  459.     
  460.     memset(EnemyHits,0,sizeof(EnemyHits));
  461.     spawn_p = (Byte *)MapPtr+MapPtr->spawnlistofs;    /* Point to the spawn table */
  462.     Count = MapPtr->numspawn;        /* How many items to spawn? */
  463.     if (!Count) {
  464.         return;
  465.     }
  466.     do {
  467.         x = spawn_p[0];        /* Get the X */
  468.         y = spawn_p[1];        /* Get the y */
  469.         type = spawn_p[2];    /* Get the type */
  470.         spawn_p+=3;            /* Index past the record */
  471.         if (type<19) {
  472.             continue;
  473.         } else if (type<23) {    /* 19-22 */
  474.             SpawnPlayer(x,y,type-19);
  475.         } else if (type<59) {    /* 23-58 */
  476.             SpawnStatic(x,y,type-23);
  477.         } else if (type<90) {    /* 59-89 */
  478.             continue;
  479.         } else if (type<98) {    /* 90-97 */
  480.             SpawnDoor(x,y,type);
  481.         } else if (type == 98) {    /* 98 */
  482.             SpawnPushwall(x,y,spawn_p[0]);
  483.             ++spawn_p;
  484.         } else if (type == 99) {    /* 99 */
  485.             SpawnOut(x,y);
  486.         } else if (type == 100) {    /* 100 */
  487.             SpawnElevator(x,y);
  488.         } else if (type == 101) {    /* 101 */
  489.             SpawnSecret(x,y);
  490.         } else if (type<108) {        /* 102-107 */
  491.             continue;
  492.         } else if (type<123) {        /* 108-122 */
  493.             SpawnStand(x,y,(class_t) (type-108));
  494.         } else if (type<126) {        /* 123-125 */
  495.             continue;
  496.         } else if (type<140) {        /* 126-139 */
  497.             SpawnAmbush(x,y,(class_t) (type-126));    
  498.         }
  499.     } while (--Count);
  500.     Count = 0;
  501.     do {
  502.         if (EnemyHits[Count]) {
  503.             x = 0;
  504.             EnemyPtr = EnemySprs[Count];
  505.             do {
  506.                 WallHits[EnemyPtr[x]] = 1;
  507.                 ++x;
  508.             } while (EnemyPtr[x]);
  509.         }
  510.     } while (++Count<16);
  511. }
  512.  
  513. /**********************************
  514.  
  515.     Release the map data
  516.         
  517. **********************************/
  518.  
  519. void ReleaseMap(void)
  520. {
  521.     Word i;
  522.     if (OldMapNum) {
  523.         KillAResource(OldMapNum);    /* Make SURE it's purged! */
  524.         OldMapNum = 0;            /* Nothing loaded */
  525.         MapPtr = 0;                /* No data available */
  526.     }
  527.     i = 0;
  528.     do {
  529.         if (ArtData[i]) {
  530.             FreeSomeMem(ArtData[i]);    /* Release the wall art */
  531.             ArtData[i] = 0;
  532.         }
  533.     } while (++i<64);                /* All walls done? */
  534.     i = 1;
  535.     do {
  536.         if (SpriteArray[i]) {            /* Is this sprite loaded? */
  537.             FreeSomeMem(SpriteArray[i]);    /* Release the memory */
  538.             SpriteArray[i] = 0;
  539.         }
  540.     } while (++i<S_LASTONE);            /* All done? */
  541. }
  542.  
  543. /**********************************
  544.  
  545.     Load and initialize everything for current game level
  546.     
  547.     Spawnlist 0-(numusable-1) are the usable (door/pushwall) spawn objects
  548.     Polysegs 0-(numpushwalls-1) are four sided pushwall segs
  549.     
  550. **********************************/
  551.  
  552. Boolean SetupGameLevel(void)
  553. {
  554.     Byte *src;
  555.     Word *dest;
  556.     Word tile;
  557.     Word Count;
  558.     
  559. /* clear counts*/
  560.  
  561.     gamestate.secrettotal=0;        /* No secret items found */
  562.     gamestate.killtotal=0;            /* Noone killed */
  563.     gamestate.treasuretotal=0;        /* No treasure found */
  564.     gamestate.secretcount=0;        /* No secret areas found */
  565.     gamestate.killcount=0;            /* Noone to kill on this level */
  566.     gamestate.treasurecount = 0;    /* No treasures laid */
  567.  
  568. /* Load a level */
  569.  
  570.     ReleaseMap();                /* Free up any previous map */
  571.     OldMapNum = (MapListPtr->MapRezNum)+gamestate.mapon;    /* Which map to load */
  572.     MapPtr = LoadAResource(OldMapNum);    /* Load in the map */
  573.     if (!MapPtr) {
  574.         return FALSE;        /* Uh.. yeah... */
  575.     }
  576.     DrawPsyched(1);        /* First stage done */
  577. #ifdef __BIGENDIAN__
  578.     MapPtr->numspawn = SwapUShort(MapPtr->numspawn);    /* Fix for 68000 machines */
  579.     MapPtr->spawnlistofs = SwapUShort(MapPtr->spawnlistofs);
  580.     MapPtr->numnodes = SwapUShort(MapPtr->numnodes);
  581.     MapPtr->nodelistofs = SwapUShort(MapPtr->nodelistofs);
  582. #endif
  583.     numstatics = 0;        /* Clear out the static array */
  584.     numdoors = 0;        /* Clear out the door array */
  585.     numactors = 1;        /* player has spot 0*/
  586.     nummissiles = 0;    /* Clear out the missile array */
  587.     
  588. /* expand the byte width map to word width*/
  589.  
  590.     memset(WallHits,0,sizeof(WallHits));
  591.     src = &MapPtr->tilemap[0][0];
  592.     dest = &tilemap[0][0];
  593.     Count = 0;
  594.     do {    
  595.         tile = src[Count];        /* Get the byte tile */
  596.         if (tile & TI_BLOCKMOVE) {
  597.             tile |= TI_BLOCKSIGHT;    /* Mark as blocking my sight */
  598.             WallHits[(tile-1)&0x1F]=1;
  599.         }
  600.         dest[Count] = tile;        /* Save the new tile */
  601.     } while (++Count<MAPSIZE*MAPSIZE);
  602.  
  603.     
  604. /* let the rendering engine know about the new map*/
  605.  
  606.     NewMap();        /* Set the variables */
  607.     DrawPsyched(2);    /* Second stage */
  608.     if (!LoadWallArt()) {    /* Get the wall shapes */
  609.         return FALSE;
  610.     }
  611. /* map.tilemap is now used to hold actor numbers if the TI_ACTOR bit is set in 
  612.     the word tilemap*/
  613.     
  614.     memset(WallHits,0,sizeof(WallHits));    /* Init the wall table */
  615.     Count = 1;
  616.     do {
  617.         WallHits[Count] = 1;    /* Force the permanent sprites to load */
  618.     } while (++Count<S_VICTORY+1);
  619.     SpawnThings();    /* Create all the characters in the game level */
  620.     return LoadSpriteArt();    /* Load in the sprite art */
  621. }
  622.  
  623. /************************************
  624.  
  625.     Load in a single wall shape
  626.  
  627. ************************************/
  628.  
  629. static Boolean LoadWallShape(Word Index,Byte *DarkPtr)
  630. {
  631.     Byte *WallPtr;
  632.     Byte *Buffer;
  633.     Word WallVal;
  634.     Word j;
  635.     
  636.     Buffer = AllocSomeMem(0x4000);        /* Get memory for wall */
  637.     if (!Buffer) {
  638.         return FALSE;
  639.     }
  640.     WallVal = WallListPtr[Index+1];        /* Which resource is it? */
  641.     WallPtr = LoadAResource(WallVal&0x3fff);    /* Load the shape */
  642.     if (!WallPtr) {
  643.         FreeSomeMem(Buffer);
  644.         return FALSE;
  645.     }
  646.     DLZSS(Buffer,WallPtr,0x4000);    /* Decompress it */
  647.     if (WallVal & 0x8000) {        /* Do I need to darken it? */
  648.         j = 0;
  649.         do {
  650.             Buffer[j] = DarkPtr[Buffer[j]];    /* Use a lookup table to darken it */
  651.         } while (++j<0x4000);
  652.     }
  653.     ArtData[Index] = Buffer;            /* Save the pointer */
  654.     ReleaseAResource(WallVal&0x3fff);    /* Purge the data */
  655.     return TRUE;
  656. }
  657.  
  658. /************************************
  659.  
  660.     Load in all the wall art
  661.  
  662. ************************************/
  663.  
  664. Word LoadWallArt(void)
  665. {
  666.     Word i;
  667.     Word j;
  668.     Word RetVal;
  669.     Byte *DarkPtr;
  670.     
  671.     RetVal = FALSE;
  672.     DarkPtr = LoadAResource(MyDarkData);        /* Get my darken table */
  673.     i = 0;
  674.     do {
  675.         if (WallHits[i]) {
  676.             j = i*2;
  677.             if (!LoadWallShape(j,DarkPtr) ||
  678.                 !LoadWallShape(j+1,DarkPtr) ) {
  679.                 goto Abort;
  680.             }
  681.             DrawPsyched(j+2);
  682.         } 
  683.     } while (++i<29);
  684.     i = 59;
  685.     do {
  686.         if (!LoadWallShape(i,DarkPtr)) {
  687.             goto Abort;
  688.         }
  689.         DrawPsyched(i+2);
  690.     } while (++i<64);
  691.     RetVal = TRUE;
  692. Abort:
  693.     ReleaseAResource(MyDarkData);
  694.     return RetVal;            /* No errors */
  695. }
  696.  
  697. /***************************
  698.  
  699.     Load in all the sprites
  700.  
  701. ***************************/
  702.  
  703. Word LoadSpriteArt(void)
  704. {
  705.     Word i;
  706.     Word Length;
  707.     Byte *MyPtr;
  708.     Byte *MyNewPtr;
  709.     
  710.     i=1;
  711.     do {
  712.         if (WallHits[i]) {
  713.             MyPtr = LoadAResource(i+(428-1));    /* Get the packed file */
  714.             if (!MyPtr) {
  715.                 return FALSE;
  716.             }
  717.             Length = MyPtr[0];                /* Get the length unpacked */
  718.             Length |= MyPtr[1]<<8;
  719.             MyNewPtr = (Byte *)AllocSomeMem(Length);        /* Get memory for the sprite */
  720.             if (!MyNewPtr) {
  721.                 ReleaseAResource(i+(428-1));    
  722.                 return FALSE;
  723.             }
  724.             DLZSS(MyNewPtr,&MyPtr[2],Length);    /* Unpack it */
  725.             SpriteArray[i] = MyNewPtr;        /* Save the pointer */
  726.             ReleaseAResource(i+(428-1));        /* Release the resource */
  727.             DrawPsyched(i+66);
  728.         }
  729.     } while (++i<S_LASTONE);
  730.     DrawPsyched(66+S_LASTONE);
  731.     return TRUE;
  732. }
  733.